package br.com.gsc.vaadin;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Transactional;

import br.com.gsc.model.tableMapping.Admin;
import br.com.gsc.model.tableMapping.Company;
import br.com.gsc.model.tableMapping.Person;
import br.com.gsc.model.tableMapping.Product;
import br.com.gsc.model.tableMapping.Topic;
import br.com.gsc.model.tableMapping.TopicTypes;
import br.com.gsc.repository.objRepos.CompanyRepository;
import br.com.gsc.repository.objRepos.PersonRepository;
import br.com.gsc.repository.objRepos.ProductRepository;
import br.com.gsc.setup.AuthenticationHolder;

import com.invient.vaadin.charts.InvientCharts;
import com.invient.vaadin.charts.InvientCharts.DecimalPoint;
import com.invient.vaadin.charts.InvientCharts.SeriesType;
import com.invient.vaadin.charts.InvientCharts.XYSeries;
import com.invient.vaadin.charts.InvientChartsConfig;
import com.invient.vaadin.charts.InvientChartsConfig.AxisBase.AxisTitle;
import com.invient.vaadin.charts.InvientChartsConfig.CategoryAxis;
import com.invient.vaadin.charts.InvientChartsConfig.ColumnConfig;
import com.invient.vaadin.charts.InvientChartsConfig.HorzAlign;
import com.invient.vaadin.charts.InvientChartsConfig.NumberYAxis;
import com.invient.vaadin.charts.InvientChartsConfig.XAxis;
import com.invient.vaadin.charts.InvientChartsConfig.XAxisDataLabel;
import com.invient.vaadin.charts.InvientChartsConfig.YAxis;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.ui.AbstractSelect.Filtering;
import com.vaadin.ui.ComboBox;

@Transactional
@Configurable(preConstruction=true, autowire=Autowire.BY_TYPE)
public class TypesOfTopicsPerProduct extends GenericGraphWithRightMenu<Product, List<Topic>> {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2916447101581847749L;

	@Autowired
	private PersonRepository pRepo;
	@Autowired
	private AuthenticationHolder auth;
	@Autowired
	private ProductRepository proRepo;
	private ComboBox cbProduct;
	private Map<Product, List<Topic>> mapOfEverything = new HashMap<Product, List<Topic>>();
	private Map<Product, List<Topic>> mapFiltered = new HashMap<Product, List<Topic>>();
	@Autowired
	private CompanyRepository cRepo;;
	
	public TypesOfTopicsPerProduct(){
		Person p = pRepo.findPersonByID(auth.getAuthentication().getName());
		if(p instanceof Admin && ((Admin) p).isSuperAdmin()){
			List<Company> listOfComps = cRepo.findAll();
			for(Company c : listOfComps){
				for(Product prod : c.getListOfProducts()){
					prod.getListOfTopics().size();
					mapOfEverything.put(prod, prod.getListOfTopics());
				}
			}
		}else{
			List<Company> listOfComps = p.getListOfCompanies();
			for(Company c : listOfComps){
				Product prod = proRepo.findTProductByID(c.getId());
				mapOfEverything.put(prod, prod.getListOfTopics());
			}
		}		
		mapFiltered = mapOfEverything;
		createComponents(mapOfEverything, mapFiltered);
		cbProduct = setupProductComboBox();
		addComponentsToRightMenu(cbProduct);
	}	
	
	private ComboBox setupProductComboBox(){
		ComboBox comboBox;
		if(cbProduct == null){
			comboBox = new ComboBox();
		}else{
			comboBox = cbProduct;
		}
		comboBox.removeAllItems();
		comboBox.setWidth(100, UNITS_PERCENTAGE);		
		comboBox.setInputPrompt("Escolha um");
		comboBox.setImmediate(true);
		comboBox.setInvalidAllowed(false);
		for(Product pb : mapOfEverything.keySet()){
			comboBox.addItem(pb);
		}
		comboBox.setImmediate(true);
		comboBox.setCaption("Produto");
		comboBox.setInvalidAllowed(false);
		comboBox.setFilteringMode(Filtering.FILTERINGMODE_CONTAINS);
		comboBox.addListener(new ComboBox.ValueChangeListener(){
			/**
			 * 
			 */
			private static final long serialVersionUID = -449942385269398185L;

			public void valueChange(ValueChangeEvent event) {
				if(event.getProperty().getValue() != null){
					((Product)cbProduct.getValue()).getListOfTopics();
					updateChartWithfilteredData(mapOfEverything);
				}else{					
					resizeGraph(true);				
				}
			}
		});
		return comboBox;
	}
	
	@Override
	@Transactional
	public InvientCharts setupChart(Map<Product, List<Topic>> map){
		InvientChartsConfig chartConfig = new InvientChartsConfig();
        chartConfig.getGeneralChartConfig().setType(SeriesType.COLUMN);
        chartConfig.getTitle().setText("Tipos de topicos por Produto");        
//        chartConfig.getSubtitle().setText("SA por SA");
        
        List<String> listOfTypes = new ArrayList<String>();
        for(TopicTypes prod : TopicTypes.values()){ 
        	listOfTypes.add(prod.getName());
        }
        CategoryAxis xAxis = new CategoryAxis();
        xAxis.setCategories(null);
        xAxis.setLabel(new XAxisDataLabel());
        xAxis.getLabel().setRotation(-45);
        xAxis.getLabel().setAlign(HorzAlign.RIGHT);
        xAxis.getLabel()
                .setStyle("{ font: 'normal 9px Verdana, sans-serif' }");
      	LinkedHashSet<XAxis> xAxesSet = new LinkedHashSet<InvientChartsConfig.XAxis>();
      	xAxesSet.add(xAxis);	      	
      	chartConfig.setXAxes(xAxesSet);
      	
        // Tooltip formatter
//        chartConfig
//                .getTooltip()
//                .setFormatterJsFunc(
//                        "function() { "
////                                + " return '<b>SA   -  Data de Fechamento   - %</b><br/>' +  this.point.name + ' - '+ $wnd.Highcharts.numberFormat(this.y,1 ) +'%'"                                                               ]
//                        		+ " return this.point.name"
//                                + "}");

        NumberYAxis yAxis = new NumberYAxis();
       	yAxis.setTitle(new AxisTitle("Topicos por Produto."));
        LinkedHashSet<YAxis> yAxesSet = new LinkedHashSet<InvientChartsConfig.YAxis>();
        yAxesSet.add(yAxis);
        chartConfig.setYAxes(yAxesSet);

        InvientCharts localChart = new InvientCharts(chartConfig);               
        
        if(cbProduct != null && cbProduct.getValue() instanceof Product){
        	addSeriesToChart(localChart,(Product)cbProduct.getValue() );
        }
        	        
        localChart.setSizeFull();

        return localChart;
	}
	
	@Transactional
	private void addSeriesToChart(InvientCharts chart,Product selectedProd) {
			
		int q = 0,i = 0,p = 0,pr = 0;
		
        ColumnConfig colCfg = new ColumnConfig();
        colCfg.setPointPadding(0.2);
        colCfg.setPointWidth(20);
        colCfg.setBorderWidth(1);
		
		 XYSeries xySeries  = new XYSeries("Perguntas",SeriesType.COLUMN, colCfg); 
		 XYSeries xySeries2 = new XYSeries("Ideias",SeriesType.COLUMN, colCfg); 
		 XYSeries xySeries3 = new XYSeries("Problemas",SeriesType.COLUMN, colCfg); 
		 XYSeries xySeries4 = new XYSeries("Elogios",SeriesType.COLUMN, colCfg); 
		
		if(selectedProd != null){
			   Product prod = selectedProd;
			   for(Topic topic : prod.getListOfTopics()){		     	   
		     	   switch(topic.getTopicType()){
		     	   	case QUESTION:
		     	   		q++;
		     	   		break;
		     	   	case IDEA:
		     	   		i++;
		     	   		break;
		     	   	case PROBLEM:
		     	   		p++;
		     	   		break;
		     	   	case PRAISE:
		     	   		pr++;
		     	   		break;
		     	   }
			   }
		}
		
		DecimalPoint question = new DecimalPoint(xySeries,q);
		DecimalPoint idea = new DecimalPoint(xySeries2,i);
		DecimalPoint problem = new DecimalPoint(xySeries3,p);
		DecimalPoint praise = new DecimalPoint(xySeries4,pr);
        xySeries.addPoint(question);
        xySeries2.addPoint(idea);
        xySeries3.addPoint(problem);
        xySeries4.addPoint(praise);
        chart.addSeries(xySeries);
        chart.addSeries(xySeries2);
        chart.addSeries(xySeries3);
        chart.addSeries(xySeries4);
	}

}
